//$ID$
//
///\file SteppingAction.cc
///\brief Implemention of the SteppingAction class

#include "MSteppingAction.hh"
#include "MRunAction.hh"
#include "G4SteppingManager.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4TrackStatus.hh"
#include "G4VPhysicalVolume.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4RunManager.hh"
#include "G4ios.hh"
#include "g4root.hh"

#include "TFile.h"
#include "TTree.h"
#include <stdlib.h>
#include <fstream>
//...oooOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......

MSteppingAction::MSteppingAction()
{;}

//...oooOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......

MSteppingAction::~MSteppingAction()
{;}

//...oooOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......oooOOOOOOooo......

void MSteppingAction::UserSteppingAction(const G4Step* theStep)
{
  //Get the track of the step
  G4Track * theTrack = theStep->GetTrack();

  //G4int ParentID = theTrack->GetParentID();				//Get the track ID
  G4int trackID = theTrack->GetTrackID();
  G4String particleName = theStep->GetTrack()->GetDynamicParticle()->GetDefinition()->GetParticleName();
  G4int evtID = 0;							//Get the event ID
  const G4Event* evt = G4RunManager::GetRunManager()->GetCurrentEvent();
  if(evt) {evtID = evt->GetEventID();	}
  G4double KE = theStep -> GetTrack() -> GetKineticEnergy();		//Get the kinetic energy
  G4int Pid = theTrack -> GetParentID();				//Get the Parent ID
  G4VPhysicalVolume* volume = theStep -> GetTrack() -> GetVolume();
  G4String volumeName = volume -> GetName();
  G4double global = theTrack -> GetGlobalTime();			//Get the Global time
  G4double local = theTrack -> GetLocalTime();			//Get the Local time

  // check if it is alive
  if (particleName == "opticalphoton")	// for the 'opticalphoton'
  {
    if(theTrack->GetTrackStatus()!=fAlive)
    {

      G4ThreeVector start = theTrack -> GetVertexPosition(); 
      G4ThreeVector momentum = theTrack -> GetVertexMomentumDirection();
      G4ThreeVector final = theTrack -> GetPosition(); 

      double _x = final.y();
      double _y = final.z();
      double _z = -1500-final.x();
      if(_z<-999 && _z>-1001)
      {
          MRunAction::Event = evtID;
          MRunAction::Omit_x = start.x();
          MRunAction::Omit_y = start.y();
          MRunAction::Omit_z = start.z();
          MRunAction::KEnergy = KE*1e6;
          //cout << "Momentum ----> " << momentum.x() << "  " << momentum.y() << "  " << momentum.z() << endl;
          MRunAction::dirX = momentum.x();
          MRunAction::dirY = momentum.y();
          MRunAction::dirZ = momentum.z();
          MRunAction::Final_x = _x;
          MRunAction::Final_y = _y;
          MRunAction::Final_z = _z;
          MRunAction::ParentID = Pid;
          MRunAction::globalTime = global;
          MRunAction::localTime = local;

          MRunAction::OpticalPhoton -> Fill();
      }
      return;
    }
  }

  //cout << "Track ID == " << trackID << endl;
  if (trackID == 1)
  {
    G4StepPoint* prePoint  = theStep->GetPreStepPoint();
    G4VPhysicalVolume * prePV = prePoint->GetPhysicalVolume();
    G4String prePVname = prePV->GetName();
    G4ThreeVector P1 = prePoint ->GetPosition();
    G4StepPoint* postPoint = theStep->GetPostStepPoint(); 
    G4VPhysicalVolume * postPV = postPoint->GetPhysicalVolume();
    if (!postPV) {return;}
    G4String postPVname = postPV->GetName();
    G4ThreeVector P2 = postPoint->GetPosition();
    G4ThreeVector Pmomentum = theTrack -> GetMomentumDirection();
  
    if (prePVname == "SD_phys" && postPVname == "PEC_phys")
    {
      MRunAction::Parent_Omit_x = P2.x();
      MRunAction::Parent_Omit_y = P2.y();
      MRunAction::Parent_Omit_z = P2.z();
      MRunAction::Parent_Omit_KEnergy = KE;
      //MRunAction::Parent -> Fill();
    }
    if (prePVname == "PEC_phys" && postPVname == "Prototype_phys")
    {
      MRunAction::Parent_dirX = Pmomentum.x();
      MRunAction::Parent_dirY = Pmomentum.y();
      MRunAction::Parent_dirZ = Pmomentum.z();
      //cout << "PM ----> " << Pmomentum.x() << "  " << Pmomentum.y() << "  " << Pmomentum.z() << endl;
    }
    if (prePVname == "SM_phys" && postPVname == "Flange_phys")
    {
      MRunAction::Parent_Final_x = P2.x();
      MRunAction::Parent_Final_y = P2.y();
      MRunAction::Parent_Final_z = P2.z();
      MRunAction::Parent_KEnergy = KE;
      //MRunAction::Parent -> Fill();
    }
    if (prePVname == "SM_phys" && postPVname == "Flange_phys")
    {
      MRunAction::Parent_Final_x2 = P2.x();
      MRunAction::Parent_Final_y2 = P2.y();
      MRunAction::Parent_Final_z2 = P2.z();
      MRunAction::Parent_KEnergy2 = KE;
      MRunAction::Parent_globalTime = global;
      MRunAction::Parent -> Fill();
    }

    //return;
  }

  // check if it is primary
  if(theTrack->GetParentID()!=0) { return; }
 
  G4StepPoint * thePrePoint = theStep->GetPreStepPoint();
  G4VPhysicalVolume * thePrePV = thePrePoint->GetPhysicalVolume();
  G4String thePrePVname = thePrePV->GetName();
  // check if it is entering to the SD volume
  if(thePrePVname(0,2)=="SD") { return; }
  G4StepPoint * thePostPoint = theStep->GetPostStepPoint();
  G4VPhysicalVolume * thePostPV = thePostPoint->GetPhysicalVolume();
  if (!thePostPV) { return;}
  G4String thePostPVname = thePostPV->GetName();
  if(thePostPVname(0,2)!="SD") { //G4cout << "Hit SD!" << G4endl; 
   //G4cout << "oooOOOoooOOOoooOOOoooOOOStepping ActionOOOoooOOOoooOOOoooOOOooo" << G4endl;
   return;}

  // then suspend the track
  theTrack->SetTrackStatus(fSuspend);
}
  
